home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / toolmanager / source / prefs / execwindow.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  34KB  |  1,150 lines

  1. /*
  2.  * execwindow.c  V2.1
  3.  *
  4.  * exec edit window handling
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Exec node */
  12. struct ExecNode {
  13.                  struct Node  en_Node;
  14.                  ULONG        en_Flags;
  15.                  UWORD        en_ExecType;
  16.                  WORD         en_Priority;
  17.                  LONG         en_Delay;
  18.                  ULONG        en_Stack;
  19.                  char        *en_Command;
  20.                  char        *en_CurrentDir;
  21.                  char        *en_HotKey;
  22.                  char        *en_Output;
  23.                  char        *en_Path;
  24.                  char        *en_PubScreen;
  25.                 };
  26.  
  27. /* Window data */
  28. static struct Gadget *gl;             /* Gadget list */
  29. static struct Window *w;              /* Window */
  30. static void *aw;                      /* AppWindow pointer */
  31. static UWORD ww,wh;                   /* Window size */
  32. static struct ExecNode *CurrentNode;
  33. static ULONG CurrentGadgetNum;
  34. static BOOL ReqOpen;
  35. static struct Requester DummyReq;
  36. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  37.                       CHECKBOXIDCMP|CYCLEIDCMP|INTEGERIDCMP|STRINGIDCMP|\
  38.                       IDCMP_VANILLAKEY)
  39.  
  40. /* Gadget data */
  41. #define GAD_NAME_STR      0 /* Gadgets with labels (left side) */
  42. #define GAD_EXECTYPE      1
  43. #define GAD_COMMAND_BUT   2
  44. #define GAD_COMMAND_TXT   3
  45. #define GAD_COMMAND_STR   4
  46. #define GAD_HOTKEY_STR    5
  47. #define GAD_STACK_INT     6
  48. #define GAD_PRIORITY_INT  7
  49. #define GAD_DELAY_INT     8
  50.  
  51. #define GAD_CURDIR_BUT    9 /* Gadgets with labels (right side) */
  52. #define GAD_PATH_BUT     10
  53. #define GAD_OUTPUT_BUT   11
  54. #define GAD_PSCREEN_BUT  12
  55. #define GAD_CURDIR_TXT   13
  56. #define GAD_PATH_TXT     14
  57. #define GAD_OUTPUT_TXT   15
  58. #define GAD_PSCREEN_TXT  16
  59.  
  60. #define GAD_ARGS         17 /* Checkbox gadgets (right side) */
  61. #define GAD_TOFRONT      18
  62.  
  63. #define GAD_CURDIR_STR   19
  64. #define GAD_PATH_STR     20
  65. #define GAD_OUTPUT_STR   21
  66. #define GAD_PSCREEN_STR  22
  67.  
  68. #define GAD_OK           23 /* Button gadgets */
  69. #define GAD_CANCEL       24
  70. #define GADGETS          25
  71. static struct GadgetData gdata[GADGETS];
  72.  
  73. /* Gadget tags */
  74. static struct TagItem nametags[]={GTST_String,   NULL,
  75.                                   GTST_MaxChars, SGBUFLEN,
  76.                                   TAG_DONE};
  77.  
  78. static char *cyclelabels[]={"CLI", "WB", "ARexx", "Dock", "Hot Key", "Network",
  79.                             NULL};
  80. static struct TagItem cycletags[]={GTCY_Labels, (ULONG) cyclelabels,
  81.                                    GTCY_Active, 0,
  82.                                    TAG_DONE};
  83.  
  84. static struct TagItem commtags[]={GTST_String,   NULL,
  85.                                   GTST_MaxChars, SGBUFLEN,
  86.                                   TAG_DONE};
  87.  
  88. static struct TagItem curdtags[]={GTST_String,   NULL,
  89.                                   GTST_MaxChars, SGBUFLEN,
  90.                                   TAG_DONE};
  91.  
  92. static struct TagItem hotktags[]={GTST_String,   NULL,
  93.                                   GTST_MaxChars, SGBUFLEN,
  94.                                   TAG_DONE};
  95.  
  96. static struct TagItem outptags[]={GTST_String,   NULL,
  97.                                   GTST_MaxChars, SGBUFLEN,
  98.                                   TAG_DONE};
  99.  
  100. static struct TagItem pathtags[]={GTST_String,   NULL,
  101.                                   GTST_MaxChars, SGBUFLEN,
  102.                                   TAG_DONE};
  103.  
  104. static struct TagItem pbsctags[]={GTST_String,   NULL,
  105.                                   GTST_MaxChars, SGBUFLEN,
  106.                                   TAG_DONE};
  107.  
  108. static struct TagItem stacktags[]={GTIN_Number,   0,
  109.                                    GTIN_MaxChars, 10,
  110.                                    TAG_DONE};
  111.  
  112. static struct TagItem priotags[]={GTIN_Number,   0,
  113.                                   GTIN_MaxChars, 10,
  114.                                   TAG_DONE};
  115.  
  116. static struct TagItem delaytags[]={GTIN_Number,   0,
  117.                                    GTIN_MaxChars, 10,
  118.                                    TAG_DONE};
  119.  
  120. static struct TagItem argstags[]={GTCB_Checked, FALSE,
  121.                                   GTCB_Scaled,  TRUE,
  122.                                   TAG_DONE};
  123.  
  124. static struct TagItem tofronttags[]={GTCB_Checked, FALSE,
  125.                                      GTCB_Scaled,  TRUE,
  126.                                      TAG_DONE};
  127.  
  128. /* Gadget vanilla key data */
  129. #define KEY_NAME     0
  130. #define KEY_TYPE     1
  131. #define KEY_COMMAND  2
  132. #define KEY_HOTKEY   3
  133. #define KEY_STACK    4
  134. #define KEY_PRIO     5
  135. #define KEY_DELAY    6
  136. #define KEY_CURDIR   7
  137. #define KEY_PATH     8
  138. #define KEY_OUTPUT   9
  139. #define KEY_PSCREEN 10
  140. #define KEY_ARGS    11
  141. #define KEY_FRONT   12
  142. #define KEY_OK      13
  143. #define KEY_CANCEL  14
  144. static char KeyArray[KEY_CANCEL+1];
  145.  
  146. /* Init exec edit window */
  147. void InitExecEditWindow(UWORD left, UWORD fheight)
  148. {
  149.  ULONG llabwidth,lgadwidth,rlabwidth,rgadwidth;
  150.  ULONG cbwidth,butwidth,minstringwidth;
  151.  ULONG strheight=fheight+2;
  152.  ULONG i,tmp,yadd;
  153.  struct GadgetData *gd;
  154.  
  155.  /* Init strings */
  156.  gdata[GAD_NAME_STR].name     =AppStrings[MSG_WINDOW_NAME_GAD];
  157.  gdata[GAD_EXECTYPE].name     =AppStrings[MSG_EXECWIN_EXECTYPE_GAD];
  158.  gdata[GAD_COMMAND_BUT].name  ="";
  159.  gdata[GAD_COMMAND_TXT].name  =AppStrings[MSG_WINDOW_COMMAND_GAD];
  160.  gdata[GAD_COMMAND_STR].name  ="";
  161.  gdata[GAD_HOTKEY_STR].name   =AppStrings[MSG_WINDOW_HOTKEY_GAD];
  162.  gdata[GAD_STACK_INT].name    =AppStrings[MSG_EXECWIN_STACK_GAD];
  163.  gdata[GAD_PRIORITY_INT].name =AppStrings[MSG_EXECWIN_PRIORITY_GAD];
  164.  gdata[GAD_DELAY_INT].name    =AppStrings[MSG_EXECWIN_DELAY_GAD];
  165.  gdata[GAD_CURDIR_TXT].name   =AppStrings[MSG_EXECWIN_CURRENTDIR_GAD];
  166.  gdata[GAD_PATH_TXT].name     =AppStrings[MSG_EXECWIN_PATH_GAD];
  167.  gdata[GAD_OUTPUT_TXT].name   =AppStrings[MSG_EXECWIN_OUTPUT_GAD];
  168.  gdata[GAD_PSCREEN_TXT].name  =AppStrings[MSG_WINDOW_PUBSCREEN_GAD];
  169.  gdata[GAD_ARGS].name         =AppStrings[MSG_EXECWIN_ARGUMENTS_GAD];
  170.  gdata[GAD_TOFRONT].name      =AppStrings[MSG_EXECWIN_TOFRONT_GAD];
  171.  gdata[GAD_OK].name           =AppStrings[MSG_WINDOW_OK_GAD];
  172.  gdata[GAD_CANCEL].name       =AppStrings[MSG_WINDOW_CANCEL_GAD];
  173.  
  174.  /* Calculate maximum label width (left side) */
  175.  llabwidth=0;
  176.  gd=&gdata[GAD_NAME_STR];
  177.  for (i=GAD_NAME_STR; i<=GAD_DELAY_INT; i++, gd++)
  178.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > llabwidth)
  179.    llabwidth=tmp;
  180.  llabwidth+=INTERWIDTH;
  181.  
  182.  /* Calculate maximum gadget width (left side) */
  183.  minstringwidth=TextLength(&TmpRastPort,AppStrings[MSG_EXECWIN_NEWNAME],
  184.                            strlen(AppStrings[MSG_EXECWIN_NEWNAME]))
  185.                 +2*INTERWIDTH;
  186.  lgadwidth=minstringwidth;
  187.  
  188.  /* Calculate maximum label width (right side) */
  189.  rlabwidth=0;
  190.  gd=&gdata[GAD_CURDIR_TXT];
  191.  for (i=GAD_CURDIR_TXT; i<=GAD_PSCREEN_TXT; i++, gd++)
  192.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > rlabwidth)
  193.    rlabwidth=tmp;
  194.  rlabwidth+=INTERWIDTH;
  195.  
  196.  /* Calculate maximum gadget width (right side) */
  197.  rgadwidth=minstringwidth;
  198.  
  199.  /* Calculate maximum checkbox gadget width */
  200.  cbwidth=0;
  201.  gd=&gdata[GAD_ARGS];
  202.  for (i=GAD_ARGS; i<=GAD_TOFRONT; i++, gd++)
  203.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > cbwidth)
  204.    cbwidth=tmp;
  205.  cbwidth+=CHECKBOX_WIDTH+INTERWIDTH;
  206.  if ((rlabwidth+rgadwidth+INTERWIDTH) < cbwidth)
  207.   rgadwidth=cbwidth-rlabwidth-INTERWIDTH;
  208.  
  209.  /* Calculate minimum window width */
  210.  ww=llabwidth+lgadwidth+rlabwidth+rgadwidth+4*INTERWIDTH;
  211.  
  212.  /* Calculate button gadgets width */
  213.  gd=&gdata[GAD_OK];
  214.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  215.  gd++;
  216.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > butwidth)
  217.   butwidth=tmp;
  218.  butwidth+=2*INTERWIDTH;
  219.  if ((tmp=2*(butwidth+INTERWIDTH)) > ww) ww=tmp;
  220.  
  221.  /* window height */
  222.  wh=8*fheight+9*INTERHEIGHT+14;
  223.  
  224.  /* Init gadgets */
  225.  gd=gdata;
  226.  yadd=strheight+INTERHEIGHT;
  227.  tmp=(ww-llabwidth-lgadwidth-rlabwidth-rgadwidth-4*INTERWIDTH)/2;
  228.  lgadwidth+=tmp; /* String gadget width (left) */
  229.  rgadwidth+=tmp; /* String gadget width (right) */
  230.  llabwidth+=left;
  231.  tmp=WindowTop+INTERHEIGHT;
  232.  
  233.  /* (left side) Name string gadget */
  234.  gd->type=STRING_KIND;
  235.  gd->flags=PLACETEXT_LEFT;
  236.  gd->tags=nametags;
  237.  gd->left=llabwidth;
  238.  gd->top=tmp;
  239.  gd->width=lgadwidth;
  240.  gd->height=strheight;
  241.  tmp+=yadd;
  242.  
  243.  /* cycle gadget */
  244.  gd++;
  245.  gd->type=CYCLE_KIND;
  246.  gd->flags=PLACETEXT_LEFT;
  247.  gd->tags=cycletags;
  248.  gd->left=llabwidth;
  249.  gd->top=tmp;
  250.  gd->width=lgadwidth;
  251.  gd->height=strheight;
  252.  tmp+=yadd;
  253.  
  254.  /* Command button gadget */
  255.  gd++;
  256.  gd->name=NULL;
  257.  gd->type=GENERIC_KIND;
  258.  gd->flags=0;
  259.  gd->left=llabwidth;
  260.  gd->top=tmp;
  261.  gd->width=REQBUTTONWIDTH;
  262.  gd->height=strheight;
  263.  
  264.  /* Command text gadget */
  265.  gd++;
  266.  gd->type=TEXT_KIND;
  267.  gd->flags=PLACETEXT_LEFT;
  268.  gd->left=llabwidth;
  269.  gd->top=tmp+strheight/2;
  270.  gd->width=0;
  271.  gd->height=0;
  272.  
  273.  /* Command string gadget */
  274.  gd++;
  275.  gd->name=NULL;
  276.  gd->type=STRING_KIND;
  277.  gd->tags=commtags;
  278.  gd->left=llabwidth+REQBUTTONWIDTH;
  279.  gd->top=tmp;
  280.  gd->width=lgadwidth-REQBUTTONWIDTH;
  281.  gd->height=strheight;
  282.  tmp+=yadd;
  283.  
  284.  /* HotKey string gadget */
  285.  gd++;
  286.  gd->type=STRING_KIND;
  287.  gd->flags=PLACETEXT_LEFT;
  288.  gd->tags=hotktags;
  289.  gd->left=llabwidth;
  290.  gd->top=tmp;
  291.  gd->width=lgadwidth;
  292.  gd->height=strheight;
  293.  tmp+=yadd;
  294.  
  295.  /* Stack integer gadget */
  296.  gd++;
  297.  gd->type=INTEGER_KIND;
  298.  gd->flags=PLACETEXT_LEFT;
  299.  gd->tags=stacktags;
  300.  gd->left=llabwidth;
  301.  gd->top=tmp;
  302.  gd->width=lgadwidth;
  303.  gd->height=strheight;
  304.  tmp+=yadd;
  305.  
  306.  /* Priority integer gadget */
  307.  gd++;
  308.  gd->type=INTEGER_KIND;
  309.  gd->flags=PLACETEXT_LEFT;
  310.  gd->tags=priotags;
  311.  gd->left=llabwidth;
  312.  gd->top=tmp;
  313.  gd->width=lgadwidth;
  314.  gd->height=strheight;
  315.  tmp+=yadd;
  316.  
  317.  /* Delay integer gadget */
  318.  gd++;
  319.  gd->type=INTEGER_KIND;
  320.  gd->flags=PLACETEXT_LEFT;
  321.  gd->tags=delaytags;
  322.  gd->left=llabwidth;
  323.  gd->top=tmp;
  324.  gd->width=lgadwidth;
  325.  gd->height=strheight;
  326.  
  327.  /* (right side) Button gadgets */
  328.  llabwidth=ww-INTERWIDTH-REQBUTTONWIDTH-rgadwidth+left;
  329.  tmp=WindowTop+INTERHEIGHT;
  330.  gd++;
  331.  for (i=GAD_CURDIR_BUT; i<=GAD_PSCREEN_BUT; i++, gd++) {
  332.   gd->type=GENERIC_KIND;
  333.   gd->flags=0;
  334.   gd->left=llabwidth;
  335.   gd->top=tmp;
  336.   gd->width=REQBUTTONWIDTH;
  337.   gd->height=strheight;
  338.   tmp+=yadd;
  339.  }
  340.  
  341.  /* (right side) dummy text gadgets */
  342.  tmp=WindowTop+strheight/2+INTERHEIGHT;
  343.  for (i=GAD_CURDIR_TXT; i<=GAD_PSCREEN_TXT; i++, gd++) {
  344.   gd->type=TEXT_KIND;
  345.   gd->flags=PLACETEXT_LEFT;
  346.   gd->left=llabwidth;
  347.   gd->top=tmp;
  348.   gd->width=0;
  349.   gd->height=0;
  350.   tmp+=yadd;
  351.  }
  352.  
  353.  /* Arguments checkbox gadget */
  354.  lgadwidth=rgadwidth+rlabwidth+INTERWIDTH-cbwidth;
  355.  rlabwidth=llabwidth-rlabwidth+lgadwidth/2;
  356.  gd->type=CHECKBOX_KIND;
  357.  gd->flags=PLACETEXT_RIGHT;
  358.  gd->tags=argstags;
  359.  gd->left=rlabwidth;
  360.  gd->top=++tmp;
  361.  gd->width=CHECKBOX_WIDTH;
  362.  gd->height=fheight-INTERHEIGHT;
  363.  tmp+=yadd;
  364.  
  365.  /* ToFront checkbox gadget */
  366.  gd++;
  367.  gd->type=CHECKBOX_KIND;
  368.  gd->flags=PLACETEXT_RIGHT;
  369.  gd->tags=tofronttags;
  370.  gd->left=rlabwidth;
  371.  gd->top=tmp;
  372.  gd->width=CHECKBOX_WIDTH;
  373.  gd->height=fheight-INTERHEIGHT;
  374.  
  375.  /* Current Directory string gadget */
  376.  tmp=WindowTop+INTERHEIGHT;
  377.  llabwidth+=REQBUTTONWIDTH;
  378.  gd++;
  379.  gd->type=STRING_KIND;
  380.  gd->flags=PLACETEXT_LEFT;
  381.  gd->tags=curdtags;
  382.  gd->left=llabwidth;
  383.  gd->top=tmp;
  384.  gd->width=rgadwidth;
  385.  gd->height=strheight;
  386.  tmp+=yadd;
  387.  
  388.  /* Path string gadget */
  389.  gd++;
  390.  gd->type=STRING_KIND;
  391.  gd->flags=PLACETEXT_LEFT;
  392.  gd->tags=pathtags;
  393.  gd->left=llabwidth;
  394.  gd->top=tmp;
  395.  gd->width=rgadwidth;
  396.  gd->height=strheight;
  397.  tmp+=yadd;
  398.  
  399.  /* Output string gadget */
  400.  gd++;
  401.  gd->type=STRING_KIND;
  402.  gd->flags=PLACETEXT_LEFT;
  403.  gd->tags=outptags;
  404.  gd->left=llabwidth;
  405.  gd->top=tmp;
  406.  gd->width=rgadwidth;
  407.  gd->height=strheight;
  408.  tmp+=yadd;
  409.  
  410.  /* Public Screen string gadget */
  411.  gd++;
  412.  gd->type=STRING_KIND;
  413.  gd->flags=PLACETEXT_LEFT;
  414.  gd->tags=pbsctags;
  415.  gd->left=llabwidth;
  416.  gd->top=tmp;
  417.  gd->width=rgadwidth;
  418.  gd->height=strheight;
  419.  
  420.  /* OK button gadget */
  421.  tmp=WindowTop+7*strheight+8*INTERHEIGHT;
  422.  gd++;
  423.  gd->type=BUTTON_KIND;
  424.  gd->flags=PLACETEXT_IN;
  425.  gd->left=left;
  426.  gd->top=tmp;
  427.  gd->width=butwidth;
  428.  gd->height=fheight;
  429.  
  430.  /* Cancel button gadget */
  431.  gd++;
  432.  gd->type=BUTTON_KIND;
  433.  gd->flags=PLACETEXT_IN;
  434.  gd->left=ww-butwidth-INTERWIDTH+left;
  435.  gd->top=tmp;
  436.  gd->width=butwidth;
  437.  gd->height=fheight;
  438.  
  439.  /* Init vanilla key array */
  440.  KeyArray[KEY_NAME]   =FindVanillaKey(gdata[GAD_NAME_STR].name);
  441.  KeyArray[KEY_TYPE]   =FindVanillaKey(gdata[GAD_EXECTYPE].name);
  442.  KeyArray[KEY_COMMAND]=FindVanillaKey(gdata[GAD_COMMAND_TXT].name);
  443.  KeyArray[KEY_HOTKEY] =FindVanillaKey(gdata[GAD_HOTKEY_STR].name);
  444.  KeyArray[KEY_STACK]  =FindVanillaKey(gdata[GAD_STACK_INT].name);
  445.  KeyArray[KEY_PRIO]   =FindVanillaKey(gdata[GAD_PRIORITY_INT].name);
  446.  KeyArray[KEY_DELAY]  =FindVanillaKey(gdata[GAD_DELAY_INT].name);
  447.  KeyArray[KEY_CURDIR] =FindVanillaKey(gdata[GAD_CURDIR_TXT].name);
  448.  KeyArray[KEY_PATH]   =FindVanillaKey(gdata[GAD_PATH_TXT].name);
  449.  KeyArray[KEY_OUTPUT] =FindVanillaKey(gdata[GAD_OUTPUT_TXT].name);
  450.  KeyArray[KEY_PSCREEN]=FindVanillaKey(gdata[GAD_PSCREEN_TXT].name);
  451.  KeyArray[KEY_ARGS]   =FindVanillaKey(gdata[GAD_ARGS].name);
  452.  KeyArray[KEY_FRONT]  =FindVanillaKey(gdata[GAD_TOFRONT].name);
  453.  KeyArray[KEY_OK]     =FindVanillaKey(gdata[GAD_OK].name);
  454.  KeyArray[KEY_CANCEL] =FindVanillaKey(gdata[GAD_CANCEL].name);
  455.  
  456.  /* Init dummy requester structure */
  457.  InitRequester(&DummyReq);
  458. }
  459.  
  460. /* Free exec node */
  461. void FreeExecNode(struct Node *node)
  462. {
  463.  struct ExecNode *en=(struct ExecNode *) node;
  464.  char *s;
  465.  
  466.  if (s=en->en_Node.ln_Name) free(s);
  467.  if (s=en->en_Command) free(s);
  468.  if (s=en->en_CurrentDir) free(s);
  469.  if (s=en->en_Output) free(s);
  470.  if (s=en->en_Path) free(s);
  471.  if (s=en->en_HotKey) free(s);
  472.  if (s=en->en_PubScreen) free(s);
  473.  
  474.  /* Free node */
  475.  FreeMem(en,sizeof(struct ExecNode));
  476. }
  477.  
  478. /* Copy exec node */
  479. struct Node *CopyExecNode(struct Node *node)
  480. {
  481.  struct ExecNode *en,*orignode=(struct ExecNode *) node;
  482.  
  483.  /* Alloc memory for exec node */
  484.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  485.  
  486.   /* Got an old node? */
  487.   if (orignode) {
  488.    /* Yes, copy it */
  489.    if ((!orignode->en_Node.ln_Name || (en->en_Node.ln_Name=
  490.                                         strdup(orignode->en_Node.ln_Name))) &&
  491.        (!orignode->en_Command || (en->en_Command=
  492.                                    strdup(orignode->en_Command))) &&
  493.        (!orignode->en_CurrentDir || (en->en_CurrentDir=
  494.                                       strdup(orignode->en_CurrentDir))) &&
  495.        (!orignode->en_Output || (en->en_Output=strdup(orignode->en_Output))) &&
  496.        (!orignode->en_Path || (en->en_Path=strdup(orignode->en_Path))) &&
  497.        (!orignode->en_HotKey || (en->en_HotKey=strdup(orignode->en_HotKey))) &&
  498.        (!orignode->en_PubScreen || (en->en_PubScreen=
  499.                                      strdup(orignode->en_PubScreen)))) {
  500.     /* Copy flags & numbers */
  501.     en->en_ExecType=orignode->en_ExecType;
  502.     en->en_Flags=orignode->en_Flags;
  503.     en->en_Stack=orignode->en_Stack;
  504.     en->en_Priority=orignode->en_Priority;
  505.     en->en_Delay=orignode->en_Delay;
  506.  
  507.     /* Return pointer to new node */
  508.     return(en);
  509.    }
  510.   } else {
  511.    /* No, set defaults */
  512.    if (en->en_Node.ln_Name=strdup(AppStrings[MSG_EXECWIN_NEWNAME])) {
  513.     en->en_Flags=EXPOF_ARGS;
  514.     en->en_Stack=4096;
  515.  
  516.     /* Return pointer to new node */
  517.     return(en);
  518.    }
  519.   }
  520.  
  521.   FreeExecNode((struct Node *) en);
  522.  }
  523.  /* Call failed */
  524.  return(NULL);
  525. }
  526.  
  527. /* Create exec node from WBArg */
  528. struct Node *CreateExecNode(char *name, struct WBArg *wa)
  529. {
  530.  struct ExecNode *en;
  531.  
  532.  /* Alloc memory for exec node */
  533.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  534.   char *dirbuf;
  535.  
  536.   /* Init node */
  537.   if ((en->en_Node.ln_Name=strdup(name)) &&
  538.       (en->en_Command=strdup(wa->wa_Name)) &&
  539.       (dirbuf=malloc(4096))) {
  540.  
  541.    /* Create & copy directory name */
  542.    if (NameFromLock(wa->wa_Lock,dirbuf,4096) &&
  543.        (en->en_CurrentDir=strdup(dirbuf))) {
  544.     /* Set defaults */
  545.     en->en_ExecType=TMET_WB;
  546.     en->en_Flags=EXPOF_ARGS;
  547.     en->en_Stack=4096;
  548.  
  549.     /* All OK. */
  550.     free(dirbuf);
  551.     return(en);
  552.    }
  553.    free(dirbuf);
  554.   }
  555.   FreeExecNode((struct Node *) en);
  556.  }
  557.  /* Call failed */
  558.  return(NULL);
  559. }
  560.  
  561. /* Activate a gadget */
  562. static void MyActivateGadget(ULONG num)
  563. {
  564.  ActivateGadget(gdata[num].gadget,w,NULL);
  565. }
  566.  
  567. /* Open exec edit window */
  568. BOOL OpenExecEditWindow(struct Node *node, struct Window *parent)
  569. {
  570.  /* Copy node */
  571.  if (CurrentNode=(struct ExecNode *) CopyExecNode(node)) {
  572.   /* Set tags */
  573.   nametags[0].ti_Data=(ULONG) CurrentNode->en_Node.ln_Name;
  574.   cycletags[1].ti_Data=CurrentNode->en_ExecType;
  575.   commtags[0].ti_Data=(ULONG) CurrentNode->en_Command;
  576.   curdtags[0].ti_Data=(ULONG) CurrentNode->en_CurrentDir;
  577.   hotktags[0].ti_Data=(ULONG) CurrentNode->en_HotKey;
  578.   outptags[0].ti_Data=(ULONG) CurrentNode->en_Output;
  579.   pathtags[0].ti_Data=(ULONG) CurrentNode->en_Path;
  580.   pbsctags[0].ti_Data=(ULONG) CurrentNode->en_PubScreen;
  581.   stacktags[0].ti_Data=CurrentNode->en_Stack;
  582.   priotags[0].ti_Data=CurrentNode->en_Priority;
  583.   delaytags[0].ti_Data=CurrentNode->en_Delay;
  584.   argstags[0].ti_Data=(CurrentNode->en_Flags & EXPOF_ARGS)!=0;
  585.   tofronttags[0].ti_Data=(CurrentNode->en_Flags & EXPOF_TOFRONT)!=0;
  586.  
  587.   /* Create gadgets */
  588.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  589.    /* Open window */
  590.    if (w=OpenWindowTags(NULL,WA_Left,        parent->LeftEdge,
  591.                              WA_Top,         parent->TopEdge+WindowTop,
  592.                              WA_InnerWidth,  ww,
  593.                              WA_InnerHeight, wh,
  594.                              WA_AutoAdjust,  TRUE,
  595.                              WA_Title,       AppStrings[MSG_EXECWIN_TITLE],
  596.                              WA_PubScreen,   PublicScreen,
  597.                              WA_Flags,       WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  598.                                              WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  599.                                              WFLG_ACTIVATE,
  600.                              TAG_DONE)) {
  601.     /* Add as AppWindow */
  602.     aw=NULL;
  603.     if (WorkbenchBase && WBScreen)
  604.      /* This call fails if the Workbench is NOT running! */
  605.      aw=AddAppWindowA(0,0,w,AppMsgPort,NULL);
  606.  
  607.     /* Init requester button gadgets */
  608.     InitReqButtonGadget(gdata[GAD_COMMAND_BUT].gadget);
  609.     InitReqButtonGadget(gdata[GAD_CURDIR_BUT].gadget);
  610.     InitReqButtonGadget(gdata[GAD_PATH_BUT].gadget);
  611.     InitReqButtonGadget(gdata[GAD_OUTPUT_BUT].gadget);
  612.     InitReqButtonGadget(gdata[GAD_PSCREEN_BUT].gadget);
  613.  
  614.     /* Add gadgets to window */
  615.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  616.     RefreshGList(gl,w,NULL,(UWORD) -1);
  617.     GT_RefreshWindow(w,NULL);
  618.  
  619.     /* Activate first gadget */
  620.     MyActivateGadget(GAD_NAME_STR);
  621.  
  622.     /* Set local variables */
  623.     w->UserPort=IDCMPPort;
  624.     w->UserData=(BYTE *) HandleExecEditWindowIDCMP;
  625.     ModifyIDCMP(w,WINDOW_IDCMP);
  626.     CurrentWindow=w;
  627.     if (aw) HandleAppMsg=HandleExecEditWindowAppMsg;
  628.     ReqOpen=FALSE;
  629.  
  630.     /* Set up file requester parameters */
  631.     FileReqParms.frp_Window=w;
  632.     FileReqParms.frp_OKText=AppStrings[MSG_FILEREQ_OK_GAD];
  633.     FileReqParms.frp_Flags1=FRF_DOPATTERNS;
  634.  
  635.     /* All OK. */
  636.     return(TRUE);
  637.    }
  638.    FreeGadgets(gl);
  639.   }
  640.   FreeExecNode((struct Node *) CurrentNode);
  641.  }
  642.  /* Call failed */
  643.  return(FALSE);
  644. }
  645.  
  646. /* Close exec edit window */
  647. static void CloseExecEditWindow(void)
  648. {
  649.  /* Free resources */
  650.  RemoveGList(w,gl,(UWORD) -1);
  651.  if (aw) {
  652.   HandleAppMsg=HandleMainWindowAppMsg;
  653.   RemoveAppWindow(aw);
  654.  }
  655.  CloseWindowSafely(w);
  656.  FreeGadgets(gl);
  657. }
  658.  
  659. /* Handle application messages */
  660. void HandleExecEditWindowAppMsg(struct AppMessage *msg)
  661. {
  662.  struct WBArg *wa;
  663.  
  664.  DEBUG_PRINTF("AppMsg 0x%08lx\n",msg);
  665.  
  666.  /* Get first argument */
  667.  if (wa=msg->am_ArgList) {
  668.   BPTR olddir;
  669.   struct DiskObject *dobj;
  670.  
  671.   DEBUG_PRINTF("Argument 0x%08lx\n",wa);
  672.  
  673.   /* Go to new current dir */
  674.   olddir=CurrentDir(wa->wa_Lock);
  675.  
  676.   /* Get icon */
  677.   if (dobj=GetDiskObjectNew(wa->wa_Name)) {
  678.    char *command=NULL;
  679.  
  680.    /* Get program name */
  681.    switch (dobj->do_Type) {
  682.     case WBTOOL:
  683.     case WBPROJECT: command=(char *) wa->wa_Name;
  684.                     break;
  685.     default:        DisplayBeep(NULL);
  686.                     break;
  687.    }
  688.  
  689.    /* Command string valid? */
  690.    if (command) {
  691.     char *dirbuf;
  692.  
  693.     /* Allocate memory for directory buffer */
  694.     if (dirbuf=malloc(4096)) {
  695.      /* Get current dir name */
  696.      if (NameFromLock(wa->wa_Lock,dirbuf,4096)) {
  697.       /* Set new gadget values */
  698.       CurrentNode->en_ExecType=TMET_WB;
  699.       GT_SetGadgetAttrs(gdata[GAD_EXECTYPE].gadget,w,NULL,
  700.                         GTCY_Active,TMET_WB,TAG_DONE);
  701.       GT_SetGadgetAttrs(gdata[GAD_NAME_STR].gadget,w,NULL,
  702.                         GTST_String,wa->wa_Name,TAG_DONE);
  703.       GT_SetGadgetAttrs(gdata[GAD_COMMAND_STR].gadget,w,NULL,
  704.                         GTST_String,command,TAG_DONE);
  705.       GT_SetGadgetAttrs(gdata[GAD_CURDIR_STR].gadget,w,NULL,
  706.                         GTST_String,dirbuf,TAG_DONE);
  707.  
  708.       /* Tool? */
  709.       if (dobj->do_Type==WBTOOL)
  710.        /* Yes, set stack */
  711.        GT_SetGadgetAttrs(gdata[GAD_STACK_INT].gadget,w,NULL,
  712.                          GTIN_Number,dobj->do_StackSize,TAG_DONE);
  713.      }
  714.      free(dirbuf);
  715.     }
  716.    }
  717.  
  718.    /* Free icon */
  719.    FreeDiskObject(dobj);
  720.   } else
  721.    DisplayBeep(NULL);
  722.   CurrentDir(olddir);
  723.  }
  724. }
  725.  
  726. /* Command gadget function */
  727. static void CommandGadgetFunc(void)
  728. {
  729.  char *file;
  730.  struct Gadget *g=gdata[GAD_COMMAND_STR].gadget;
  731.  
  732.  /* Dock exec type? */
  733.  if (CurrentNode->en_ExecType==TMET_Dock) {
  734.   /* Yes. Open list requester */
  735.   if (!ReqOpen && OpenListRequester(LISTREQ_DOCK,w)) {
  736.    /* Disable window */
  737.    DisableWindow(w,&DummyReq);
  738.  
  739.    /* Save gadget number */
  740.    CurrentGadgetNum=GAD_COMMAND_STR;
  741.  
  742.    /* Set update function */
  743.    UpdateWindow=UpdateExecEditWindow;
  744.    ReqOpen=TRUE;
  745.   }
  746.  } else {
  747.   /* No. Set file requester parameters */
  748.   FileReqParms.frp_Title=AppStrings[MSG_FILEREQ_TITLE_FILE];
  749.   FileReqParms.frp_Flags2=FRF_REJECTICONS;
  750.   FileReqParms.frp_OldFile=((struct StringInfo *) g->SpecialInfo)->Buffer;
  751.  
  752.   /* Open file requester */
  753.   if (file=OpenFileRequester(&DummyReq)) {
  754.    /* Set new file string */
  755.    GT_SetGadgetAttrs(g,w,NULL,GTST_String,file, TAG_DONE);
  756.    free(file);
  757.   }
  758.  }
  759.  
  760.  /* Activate command string gadget */
  761.  ActivateGadget(g,w,NULL);
  762. }
  763.  
  764. /* Current directory gadget function */
  765. static void CurDirGadgetFunc(void)
  766. {
  767.  char *file;
  768.  struct Gadget *g=gdata[GAD_CURDIR_STR].gadget;
  769.  
  770.  /* Set file requester parameters */
  771.  FileReqParms.frp_Title=AppStrings[MSG_FILEREQ_TITLE_DRAWER];
  772.  FileReqParms.frp_Flags2=FRF_DRAWERSONLY|FRF_REJECTICONS;
  773.  FileReqParms.frp_OldFile=((struct StringInfo *) g->SpecialInfo)->Buffer;
  774.  
  775.  /* Open file requester */
  776.  if (file=OpenFileRequester(&DummyReq)) {
  777.   /* Set new file string */
  778.   GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,TAG_DONE);
  779.   free(file);
  780.  }
  781.  
  782.  /* Activate current directory string gadget */
  783.  ActivateGadget(g,w,NULL);
  784. }
  785.  
  786. /* Path gadget function */
  787. static void PathGadgetFunc(void)
  788. {
  789.  char *file;
  790.  struct Gadget *g=gdata[GAD_PATH_STR].gadget;
  791.  
  792.  /* Set file requester parameters */
  793.  FileReqParms.frp_Title=AppStrings[MSG_FILEREQ_TITLE_DRAWER];
  794.  FileReqParms.frp_Flags2=FRF_DRAWERSONLY|FRF_REJECTICONS;
  795.  FileReqParms.frp_OldFile="";
  796.  
  797.  /* Open file requester */
  798.  if (file=OpenFileRequester(&DummyReq)) {
  799.   char *oldpath,*path;
  800.   ULONG len;
  801.  
  802.   oldpath=((struct StringInfo *) g->SpecialInfo)->Buffer;
  803.   len=strlen(oldpath);
  804.  
  805.   /* Alloc memory for new path string */
  806.   if (path=malloc(len+strlen(file)+2)) {
  807.    /* Build new path string. Got old path? */
  808.    if (len) {
  809.     /* Yes. Append new path */
  810.     strcpy(path,oldpath);
  811.     path[len]=';';
  812.     strcpy(path+len+1,file);
  813.    } else
  814.     /* No. Copy new path */
  815.     strcpy(path,file);
  816.  
  817.    /* Set new path string */
  818.    GT_SetGadgetAttrs(g,w,NULL,GTST_String,path,TAG_DONE);
  819.    free(path);
  820.   }
  821.   free(file);
  822.  }
  823.  
  824.  /* Activate path string gadget */
  825.  ActivateGadget(g,w,NULL);
  826. }
  827.  
  828. /* Output gadget function */
  829. static void OutputGadgetFunc(void)
  830. {
  831.  char *file;
  832.  struct Gadget *g=gdata[GAD_OUTPUT_STR].gadget;
  833.  
  834.  /* Set file requester parameters */
  835.  FileReqParms.frp_Title=AppStrings[MSG_FILEREQ_TITLE_FILE];
  836.  FileReqParms.frp_Flags2=FRF_REJECTICONS;
  837.  FileReqParms.frp_OldFile=((struct StringInfo *) g->SpecialInfo)->Buffer;
  838.  
  839.  /* Open file requester */
  840.  if (file=OpenFileRequester(&DummyReq)) {
  841.   /* Set new file string */
  842.   GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,TAG_DONE);
  843.   free(file);
  844.  }
  845.  
  846.  /* Activate output string gadget */
  847.  ActivateGadget(g,w,NULL);
  848. }
  849.  
  850. /* Public screen gadget function */
  851. static void PubScreenGadgetFunc(void)
  852. {
  853.  /* Open list requester */
  854.  if (!ReqOpen && OpenListRequester(LISTREQ_PUBSC,w)) {
  855.   /* Disable window */
  856.   DisableWindow(w,&DummyReq);
  857.  
  858.   /* Save gadget number */
  859.   CurrentGadgetNum=GAD_PSCREEN_STR;
  860.  
  861.   /* Set update function */
  862.   UpdateWindow=UpdateExecEditWindow;
  863.   ReqOpen=TRUE;
  864.  }
  865. }
  866.  
  867. /* OK gadget function */
  868. static struct Node *OKGadgetFunc(void)
  869. {
  870.  struct Node *rc;
  871.  
  872.  char *s;
  873.  
  874.  /* Free old strings */
  875.  if (s=CurrentNode->en_Node.ln_Name) free(s);
  876.  CurrentNode->en_Node.ln_Name=NULL;
  877.  if (s=CurrentNode->en_Command) free(s);
  878.  CurrentNode->en_Command=NULL;
  879.  if (s=CurrentNode->en_CurrentDir) free(s);
  880.  CurrentNode->en_CurrentDir=NULL;
  881.  if (s=CurrentNode->en_Output) free(s);
  882.  CurrentNode->en_Output=NULL;
  883.  if (s=CurrentNode->en_Path) free(s);
  884.  CurrentNode->en_Path=NULL;
  885.  if (s=CurrentNode->en_HotKey) free(s);
  886.  CurrentNode->en_HotKey=NULL;
  887.  if (s=CurrentNode->en_PubScreen) free(s);
  888.  CurrentNode->en_PubScreen=NULL;
  889.  
  890.  /* Duplicate new strings */
  891.  if (((CurrentNode->en_Node.ln_Name=
  892.         DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) &&
  893.      ((CurrentNode->en_Command=
  894.         DuplicateBuffer(gdata[GAD_COMMAND_STR].gadget)) != (char *) -1) &&
  895.      ((CurrentNode->en_CurrentDir=
  896.         DuplicateBuffer(gdata[GAD_CURDIR_STR].gadget)) != (char *) -1) &&
  897.      ((CurrentNode->en_Output=
  898.         DuplicateBuffer(gdata[GAD_OUTPUT_STR].gadget)) != (char *) -1) &&
  899.      ((CurrentNode->en_Path=
  900.         DuplicateBuffer(gdata[GAD_PATH_STR].gadget)) != (char *) -1) &&
  901.      ((CurrentNode->en_HotKey=
  902.         DuplicateBuffer(gdata[GAD_HOTKEY_STR].gadget)) != (char *) -1) &&
  903.      ((CurrentNode->en_PubScreen=
  904.         DuplicateBuffer(gdata[GAD_PSCREEN_STR].gadget)) != (char *) -1)) {
  905.   /* Copy integer gadget values */
  906.   CurrentNode->en_Stack=
  907.    ((struct StringInfo *) gdata[GAD_STACK_INT].gadget->SpecialInfo)->LongInt;
  908.   CurrentNode->en_Priority=
  909.    ((struct StringInfo *) gdata[GAD_PRIORITY_INT].gadget->SpecialInfo)
  910.     ->LongInt;
  911.   CurrentNode->en_Delay=
  912.    ((struct StringInfo *) gdata[GAD_DELAY_INT].gadget->SpecialInfo)->LongInt;
  913.  
  914.   rc=(struct Node *) CurrentNode;
  915.  } else {
  916.   /* Couldn't copy strings */
  917.   rc=(struct Node *) -1;
  918.   FreeExecNode((struct Node *) CurrentNode);
  919.  }
  920.  return(rc);
  921. }
  922.  
  923. /* Handle exec edit window IDCMP events */
  924. void *HandleExecEditWindowIDCMP(struct IntuiMessage *msg)
  925. {
  926.  struct Node *NewNode=NULL;
  927.  
  928.  /* Which IDCMP class? */
  929.  switch (msg->Class) {
  930.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  931.                             FreeExecNode((struct Node *) CurrentNode);
  932.                             break;
  933.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  934.                             GT_EndRefresh(w,TRUE);
  935.                             break;
  936.   case IDCMP_GADGETUP:
  937.    switch (((struct Gadget *) msg->IAddress) ->GadgetID) {
  938.     case GAD_EXECTYPE:    /* Save type */
  939.                           CurrentNode->en_ExecType=msg->Code;
  940.                           break;
  941.     case GAD_COMMAND_BUT: CommandGadgetFunc();
  942.                           break;
  943.     case GAD_CURDIR_BUT:  CurDirGadgetFunc();
  944.                           break;
  945.     case GAD_PATH_BUT:    PathGadgetFunc();
  946.                           break;
  947.     case GAD_OUTPUT_BUT:  OutputGadgetFunc();
  948.                           break;
  949.     case GAD_PSCREEN_BUT: PubScreenGadgetFunc();
  950.                           break;
  951.     case GAD_ARGS:        /* Toggle flag */
  952.                           CurrentNode->en_Flags^=EXPOF_ARGS;
  953.                           break;
  954.     case GAD_TOFRONT:     /* Toggle flag */
  955.                           CurrentNode->en_Flags^=EXPOF_TOFRONT;
  956.                           break;
  957.     case GAD_OK:          NewNode=OKGadgetFunc();
  958.                           break;
  959.     case GAD_CANCEL:      NewNode=(struct Node *) -1;
  960.                           FreeExecNode((struct Node *) CurrentNode);
  961.                           break;
  962.    }
  963.    break;
  964.   case IDCMP_VANILLAKEY:
  965.    switch (MatchVanillaKey(msg->Code,KeyArray)) {
  966.     case KEY_NAME:    MyActivateGadget(GAD_NAME_STR);
  967.                       break;
  968.     case KEY_TYPE:    {
  969.                        /* Get next cycle gadget code */
  970.                        ULONG oldtype=CurrentNode->en_ExecType;
  971.                        ULONG newtype;
  972.  
  973.                        /* Forward or backward cycle */
  974.                        if (islower(msg->Code))
  975.                         newtype=(oldtype+1) % (TMET_Network+1);
  976.                        else
  977.                         newtype=(oldtype>0) ? oldtype-1 : TMET_Network;
  978.  
  979.                        /* Set cycle gadget */
  980.                        GT_SetGadgetAttrs(gdata[GAD_EXECTYPE].gadget,w,NULL,
  981.                                          GTCY_Active, newtype,
  982.                                          TAG_DONE);
  983.  
  984.                        /* Save type */
  985.                        CurrentNode->en_ExecType=newtype;
  986.                       }
  987.                       break;
  988.     case KEY_COMMAND: CommandGadgetFunc();
  989.                       break;
  990.     case KEY_HOTKEY:  MyActivateGadget(GAD_HOTKEY_STR);
  991.                       break;
  992.     case KEY_STACK:   MyActivateGadget(GAD_STACK_INT);
  993.                       break;
  994.     case KEY_PRIO:    MyActivateGadget(GAD_PRIORITY_INT);
  995.                       break;
  996.     case KEY_DELAY:   MyActivateGadget(GAD_DELAY_INT);
  997.                       break;
  998.     case KEY_CURDIR:  CurDirGadgetFunc();
  999.                       break;
  1000.     case KEY_PATH:    PathGadgetFunc();
  1001.                       break;
  1002.     case KEY_OUTPUT:  OutputGadgetFunc();
  1003.                       break;
  1004.     case KEY_PSCREEN: PubScreenGadgetFunc();
  1005.                       break;
  1006.     case KEY_ARGS:    /* Toggle flag */
  1007.                       CurrentNode->en_Flags^=EXPOF_ARGS;
  1008.  
  1009.                       /* Set check box gadget */
  1010.                       GT_SetGadgetAttrs(gdata[GAD_ARGS].gadget,w,NULL,
  1011.                        GTCB_Checked, (CurrentNode->en_Flags & EXPOF_ARGS),
  1012.                        TAG_DONE);
  1013.  
  1014.                       break;
  1015.     case KEY_FRONT:   /* Toggle flag */
  1016.                       CurrentNode->en_Flags^=EXPOF_TOFRONT;
  1017.  
  1018.                       /* Set check box gadget */
  1019.                       GT_SetGadgetAttrs(gdata[GAD_TOFRONT].gadget,w,NULL,
  1020.                        GTCB_Checked, (CurrentNode->en_Flags & EXPOF_TOFRONT),
  1021.                        TAG_DONE);
  1022.  
  1023.                       break;
  1024.     case KEY_OK:      NewNode=OKGadgetFunc();
  1025.                       break;
  1026.     case KEY_CANCEL:  NewNode=(struct Node *) -1;
  1027.                       FreeExecNode((struct Node *) CurrentNode);
  1028.                       break;
  1029.    }
  1030.    break;
  1031.  }
  1032.  
  1033.  /* Close window? */
  1034.  if (NewNode) {
  1035.   /* Yes. But first reply message!!! */
  1036.   GT_ReplyIMsg(msg);
  1037.   CloseExecEditWindow();
  1038.  }
  1039.  
  1040.  return(NewNode);
  1041. }
  1042.  
  1043. /* Update Exec edit window */
  1044. void UpdateExecEditWindow(void *data)
  1045. {
  1046.  /* Got data? */
  1047.  if (data != LREQRET_CANCEL) {
  1048.   struct Gadget *g=gdata[CurrentGadgetNum].gadget;
  1049.   char *new;
  1050.  
  1051.   /* Selected something? */
  1052.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  1053.  
  1054.   /* Set new public screen name */
  1055.   GT_SetGadgetAttrs(g,w,NULL,GTST_String,new,
  1056.                              TAG_DONE);
  1057.  
  1058.   /* Activate string gadget */
  1059.   ActivateGadget(g,w,NULL);
  1060.  }
  1061.  
  1062.  /* Enable window */
  1063.  EnableWindow(w,&DummyReq,WINDOW_IDCMP);
  1064.  
  1065.  /* Restore update function pointer */
  1066.  UpdateWindow=UpdateMainWindow;
  1067.  CurrentWindow=w;
  1068.  ReqOpen=FALSE;
  1069. }
  1070.  
  1071. /* Read TMEX IFF chunk into Exec node */
  1072. struct Node *ReadExecNode(UBYTE *buf)
  1073. {
  1074.  struct ExecNode *en;
  1075.  
  1076.  /* Allocate memory for node */
  1077.  if (en=AllocMem(sizeof(struct ExecNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  1078.   struct ExecPrefsObject *epo=(struct ExecPrefsObject *) buf;
  1079.   ULONG sbits=epo->epo_StringBits;
  1080.   UBYTE *ptr=(UBYTE *) &epo[1];
  1081.  
  1082.   if ((!(sbits & EXPO_NAME) || (en->en_Node.ln_Name=GetConfigStr(&ptr))) &&
  1083.       (!(sbits & EXPO_COMMAND) || (en->en_Command=GetConfigStr(&ptr))) &&
  1084.       (!(sbits & EXPO_CURDIR) || (en->en_CurrentDir=GetConfigStr(&ptr))) &&
  1085.       (!(sbits & EXPO_HOTKEY) || (en->en_HotKey=GetConfigStr(&ptr))) &&
  1086.       (!(sbits & EXPO_OUTPUT) || (en->en_Output=GetConfigStr(&ptr))) &&
  1087.       (!(sbits & EXPO_PATH) || (en->en_Path=GetConfigStr(&ptr))) &&
  1088.       (!(sbits & EXPO_PSCREEN) || (en->en_PubScreen=GetConfigStr(&ptr)))) {
  1089.    /* Copy flags & values */
  1090.    en->en_Flags=epo->epo_Flags;
  1091.    en->en_ExecType=epo->epo_ExecType;
  1092.    en->en_Priority=epo->epo_Priority;
  1093.    en->en_Delay=epo->epo_Delay;
  1094.    en->en_Stack=epo->epo_Stack;
  1095.  
  1096.    /* All OK. */
  1097.    return(en);
  1098.   }
  1099.  
  1100.   /* Call failed */
  1101.   FreeExecNode((struct Node *) en);
  1102.  }
  1103.  return(NULL);
  1104. }
  1105.  
  1106. /* Write Exec node to TMEX IFF chunk */
  1107. BOOL WriteExecNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  1108. {
  1109.  struct ExecNode *en=(struct ExecNode *) node;
  1110.  struct ExecPrefsObject *epo=(struct ExecPrefsObject *) buf;
  1111.  ULONG sbits=0;
  1112.  UBYTE *ptr=(UBYTE *) &epo[1];
  1113.  
  1114.  /* Copy strings */
  1115.  if (PutConfigStr(en->en_Node.ln_Name,&ptr)) sbits|=EXPO_NAME;
  1116.  if (PutConfigStr(en->en_Command,&ptr)) sbits|=EXPO_COMMAND;
  1117.  if (PutConfigStr(en->en_CurrentDir,&ptr)) sbits|=EXPO_CURDIR;
  1118.  if (PutConfigStr(en->en_HotKey,&ptr)) sbits|=EXPO_HOTKEY;
  1119.  if (PutConfigStr(en->en_Output,&ptr)) sbits|=EXPO_OUTPUT;
  1120.  if (PutConfigStr(en->en_Path,&ptr)) sbits|=EXPO_PATH;
  1121.  if (PutConfigStr(en->en_PubScreen,&ptr)) sbits|=EXPO_PSCREEN;
  1122.  
  1123.  /* set string bits */
  1124.  epo->epo_StringBits=sbits;
  1125.  
  1126.  /* Copy flags & values */
  1127.  epo->epo_Flags=en->en_Flags;
  1128.  epo->epo_ExecType=en->en_ExecType;
  1129.  epo->epo_Priority=en->en_Priority;
  1130.  epo->epo_Delay=en->en_Delay;
  1131.  epo->epo_Stack=en->en_Stack;
  1132.  
  1133.  /* calculate length */
  1134.  sbits=ptr-buf;
  1135.  
  1136.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  1137.  
  1138.  /* Open chunk */
  1139.  if (PushChunk(iff,0,ID_TMEX,sbits)) return(FALSE);
  1140.  
  1141.  /* Write chunk */
  1142.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  1143.  
  1144.  /* Close chunk */
  1145.  if (PopChunk(iff)) return(FALSE);
  1146.  
  1147.  /* All OK. */
  1148.  return(TRUE);
  1149. }
  1150.